package repo

import (
	"context"
	"gitlab.yoyiit.com/youyi/go-core/handler"
	"gitlab.yoyiit.com/youyi/go-core/repository"
	"gitlab.yoyiit.com/youyi/go-core/util"
)

type CounterpartyPermissionDBData struct {
	repository.BaseDBData
	CounterpartyId        int64  //关联的交易对手ID
	CounterpartyContactId int64  //交易对手联系方式ID
	UserId                int64  //用户ID
	Username              string //用户名称
	Nickname              string //用户昵称
	PermissionType        int64  //权限类型

}

type CounterpartyPermissionDBDataParam struct {
	CounterpartyPermissionDBData
	Ids []int64
}

func (*CounterpartyPermissionDBData) TableName() string {
	return "counterparty_permission"
}

func (param *CounterpartyPermissionDBData) getConditions() []*repository.Condition {
	return []*repository.Condition{
		repository.NewAndCondition(param),
	}
}

func (param *CounterpartyPermissionDBDataParam) listConditions() []*repository.Condition {
	var conditions []*repository.Condition

	if param.Ids != nil {
		conditions = append(conditions, repository.NewAndCondition("id in ?", param.Ids))
	}

	if param.CounterpartyId != 0 {
		conditions = append(conditions, repository.NewAndCondition("counterparty_id = ?", param.CounterpartyId))
	}
	if param.CounterpartyContactId != 0 {
		conditions = append(conditions, repository.NewAndCondition("counterparty_contact_id = ?", param.CounterpartyContactId))
	}
	if param.UserId != 0 {
		conditions = append(conditions, repository.NewAndCondition("user_id = ?", param.UserId))
	}
	if param.Username != "" {
		conditions = append(conditions, repository.NewAndCondition("username = ?", param.Username))
	}

	if param.Nickname != "" {
		conditions = append(conditions, repository.NewAndCondition("nickname = ?", param.Nickname))
	}

	if param.PermissionType != 0 {
		conditions = append(conditions, repository.NewAndCondition("permission_type = ?", param.PermissionType))
	}

	return conditions
}

type CounterpartyPermissionRepo interface {
	repository.BaseCommonRepo
	Get(context.Context, *CounterpartyPermissionDBData) (*CounterpartyPermissionDBData, error)
	Count(context.Context, *CounterpartyPermissionDBDataParam) (int64, error)
	List(context.Context, string, int32, int32, *CounterpartyPermissionDBDataParam) (*[]CounterpartyPermissionDBData, int64, error)
	SimpleList(ctx context.Context, order string, pageNum, pageSize int32, param *CounterpartyPermissionDBDataParam) (*[]CounterpartyPermissionDBData, int64, error)
}

type counterpartyPermissionRepo struct {
	repository.BaseRepo
}

func (r *counterpartyPermissionRepo) Get(ctx context.Context, param *CounterpartyPermissionDBData) (*CounterpartyPermissionDBData, error) {
	data, err := r.BaseGet(ctx, repository.NewQueryBuilder().Where(param.getConditions()))
	if data == nil {
		return nil, handler.HandleError(err)
	}
	return data.(*CounterpartyPermissionDBData), handler.HandleError(err)
}

func (r *counterpartyPermissionRepo) List(ctx context.Context, order string, pageNum, pageSize int32, param *CounterpartyPermissionDBDataParam) (*[]CounterpartyPermissionDBData, int64, error) {
	data, count, err := r.BaseList(ctx, repository.NewListQueryBuilder(order, pageNum, pageSize).Where(param.listConditions()))
	if data == nil {
		return nil, count, handler.HandleError(err)
	}
	return data.(*[]CounterpartyPermissionDBData), count, handler.HandleError(err)
}

func (r *counterpartyPermissionRepo) SimpleList(ctx context.Context, order string, pageNum, pageSize int32, param *CounterpartyPermissionDBDataParam) (*[]CounterpartyPermissionDBData, int64, error) {
	conditions := []string{}
	params := []interface{}{}

	if param.ClinicalDocument != "" {
		conditions = append(conditions, "clinical_document = ?")
		params = append(params, param.ClinicalDocument)
	}
	if param.CounterpartyId != "" {
		conditions = append(conditions, "counterparty_id = ?")
		params = append(params, param.CounterpartyId)
	}
	if param.CounterpartyContactId != "" {
		conditions = append(conditions, "counterparty_contact_id = ?")
		params = append(params, param.CounterpartyContactId)
	}
	if param.UserId != "" {
		conditions = append(conditions, "user_id = ?")
		params = append(params, param.UserId)
	}
	if param.Username != "" {
		conditions = append(conditions, "username = ?")
		params = append(params, param.Username)
	}
	if param.Nickname != "" {
		conditions = append(conditions, "nickname = ?")
		params = append(params, param.Nickname)
	}
	if param.PermissionType != "" {
		conditions = append(conditions, "permission_type = ?")
		params = append(params, param.PermissionType)
	}

	var count int64
	err := r.Db.WithContext(ctx).Model(r.Model).Where(strings.Join(conditions, " and "), params...).Count(&count).Error
	if err != nil {
		return nil, 0, handler.HandleError(err)
	}
	if count == 0 {
		return nil, 0, nil
	}
	var result []CounterpartyPermissionDBData
	db := r.Db.WithContext(ctx).Where(strings.Join(conditions, " and "), params...)
	if order != "" {
		db = db.Order(order)
	}
	if pageNum > 0 && pageSize > 0 {
		db = db.Offset(int((pageNum - 1) * pageSize))
		db = db.Limit(int(pageSize))
	}
	err = db.Find(&result).Error
	return &result, count, handler.HandleError(err)
}

func (r *counterpartyPermissionRepo) Count(ctx context.Context, param *CounterpartyPermissionDBDataParam) (int64, error) {
	count, err := r.BaseCount(ctx, repository.NewQueryBuilder().Where(param.listConditions()))
	return count, handler.HandleError(err)
}
